package megadrum.gui;

import megadrum.*;
import megadrum.mididata.MidiCommon;
import megadrum.mididata.SysexFile;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;

public class Options extends javax.swing.JDialog implements ActionListener, ItemListener {

    public Options(MegadrumConfigTool mct) {
        super(mct, true);
        parent = mct;

        //auto-generated method to initialize GUI
        initComponents();

        //set saved previous selection
        mcu.addItemListener(this);
        mcu.setModel(new javax.swing.DefaultComboBoxModel(Common.MCUS));
        mcu.setSelectedItem("Atmega" + parent.getMCU());

        //set saved previous selection
        inputs.setModel(new javax.swing.DefaultComboBoxModel(Common.NUM_INPUTS[mcu.getSelectedIndex()]));
        inputs.setSelectedItem("" + (parent.getNumberOfInputs() + 1));
        selectedInputs = inputs.getSelectedIndex();

        //set saved previous selection
        clock.setModel(new javax.swing.DefaultComboBoxModel(Common.CLOCKS));
        clock.setSelectedItem(parent.getClock() + "Mhz");

        //set saved previous selection
        bootloader.setModel(new javax.swing.DefaultComboBoxModel(Common.BOOTLOADERS));
        bootloader.setSelectedIndex(parent.getBootloader());

        //set saved previous selection
        chainID.setSelectedIndex(parent.getChainID());

        //set saved previous selection
        fillInList();
        input.setSelectedItem(parent.getInputDeviceName());
        fillOutputList();
        output.setSelectedItem(parent.getOutputDeviceName());
        fillThroughList();
        through.setSelectedItem(parent.getThroughDeviceName());
        
        //listeners for Midi devices panel
        useSameDevice.addItemListener(this);
        input.addItemListener(this);
        output.addItemListener(this);

        //if the input and output are the same, configure the GUI to show correct state
        if( (parent.getInputDeviceName()==null && parent.getInputDeviceName()==null)
                || ( parent.getInputDeviceName()!=null && parent.getOutputDeviceName()!=null &&
                parent.getInputDeviceName().equals(parent.getOutputDeviceName()) ) ){
            useSameDevice.setSelected(true); //the item listener will configure the GUI for us
        }

        //set saved previous selection
        enableMidiThrough.addItemListener(this);
        enableMidiThrough.setSelected(parent.getThroughDeviceName()!=null);

        //set saved previous selection
        enableLiveEditing.setSelected(parent.getLiveEditingEnabled());
        enableLoadAtStartup.setSelected(parent.getLoadAtStartupEnabled());

        //set saved previous selection
        enableQuickAccess.addItemListener(this);
        enableQuickAccess.setSelected(parent.getQuickAccessEnabled());
        qaPad.setModel(new CustomSpinnerIntModel(40, 0, 126, 1));
        qaPedal.setModel(new CustomSpinnerIntModel(40, 1, 127, 1));
        ((CustomSpinnerModel) qaPad.getModel()).setIntValue(parent.getQuickAccessPadThreshold());
        ((CustomSpinnerModel) qaPedal.getModel()).setIntValue(parent.getQuickAccessPedalThreshold());
        ((JSpinner.DefaultEditor) qaPad.getEditor()).getTextField().setBackground(java.awt.Color.WHITE);
        ((JSpinner.DefaultEditor) qaPad.getEditor()).getTextField().setForeground(java.awt.Color.BLACK);
        ((JSpinner.DefaultEditor) qaPedal.getEditor()).getTextField().setBackground(java.awt.Color.WHITE);
        ((JSpinner.DefaultEditor) qaPedal.getEditor()).getTextField().setForeground(java.awt.Color.BLACK);

        //set saved previous selection
        rimSwitch.setSelectedIndex((int) (parent.getRimSwitchThreshold() / 10.0));

        //set saved wait time
        waitTime.setModel(new CustomSpinnerIntModel(100, 0, 1000, 10));
//        new PopupSlider(waitTime);
        ((JSpinner.DefaultEditor) waitTime.getEditor()).getTextField().setBackground(java.awt.Color.WHITE);
        ((JSpinner.DefaultEditor) waitTime.getEditor()).getTextField().setForeground(java.awt.Color.BLACK);
        ((CustomSpinnerModel) waitTime.getModel()).setIntValue(parent.getSysexWaitTime());

        //set saved previous selection
        lookandfeel.addItemListener(this);
        lookandfeel.setModel(new javax.swing.DefaultComboBoxModel(Common.LOOKANDFEELS));
        lookandfeel.setSelectedIndex((1 + parent.getLookAndFeel()) % Common.LOOKANDFEELS.length);
        lookandfeel.setSelectedIndex(parent.getLookAndFeel());
        theme.setSelectedIndex(parent.getTheme());
        selectedLook = lookandfeel.getSelectedIndex();
        selectedTheme = theme.getSelectedIndex();

        //init rest of components
        apply.addActionListener(this);

        //center app window on screen
        setLocationRelativeTo(mct);

        //show
        //repack the GUI
        setResizable(false);
        pack();
        setVisible(true);
        //setVisible(true);
        //this.update(this.getGraphics());
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        javax.swing.JPanel hardwarePanel = new javax.swing.JPanel();
        javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
        inputs = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel2 = new javax.swing.JLabel();
        mcu = new javax.swing.JComboBox();
        clock = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel3 = new javax.swing.JLabel();
        bootloader = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel13 = new javax.swing.JLabel();
        chainID = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel15 = new javax.swing.JLabel();
        javax.swing.JPanel midiPanel = new javax.swing.JPanel();
        inputLabel = new javax.swing.JLabel();
        input = new javax.swing.JComboBox();
        outputLabel = new javax.swing.JLabel();
        output = new javax.swing.JComboBox();
        through = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel14 = new javax.swing.JLabel();
        enableMidiThrough = new javax.swing.JCheckBox();
        useSameDevice = new javax.swing.JCheckBox();
        javax.swing.JPanel quickAccessPanel = new javax.swing.JPanel();
        enableQuickAccess = new javax.swing.JCheckBox();
        javax.swing.JLabel jLabel7 = new javax.swing.JLabel();
        javax.swing.JLabel jLabel6 = new javax.swing.JLabel();
        qaPad = new javax.swing.JSpinner();
        qaPedal = new javax.swing.JSpinner();
        javax.swing.JPanel rimSwitchPanel = new javax.swing.JPanel();
        javax.swing.JLabel jLabel9 = new javax.swing.JLabel();
        rimSwitch = new javax.swing.JComboBox();
        javax.swing.JPanel themePanel = new javax.swing.JPanel();
        javax.swing.JLabel jLabel10 = new javax.swing.JLabel();
        lookandfeel = new javax.swing.JComboBox();
        theme = new javax.swing.JComboBox();
        javax.swing.JLabel jLabel11 = new javax.swing.JLabel();
        apply = new javax.swing.JButton();
        javax.swing.JPanel sysexPanel = new javax.swing.JPanel();
        javax.swing.JLabel jLabel12 = new javax.swing.JLabel();
        waitTime = new javax.swing.JSpinner();
        javax.swing.JPanel loadSendPanel = new javax.swing.JPanel();
        enableLiveEditing = new javax.swing.JCheckBox();
        enableLoadAtStartup = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Configure options");

        hardwarePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Hardware"));

        jLabel1.setText("No. of inputs:");

        jLabel2.setText("MCU type:");

        jLabel3.setText("Clock:");

        jLabel13.setText("Bootloader:");

        chainID.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0 (default)", "1", "2", "3", "4", "5", "6", "7", "8", "9" }));

        jLabel15.setText("Chain ID:");

        org.jdesktop.layout.GroupLayout hardwarePanelLayout = new org.jdesktop.layout.GroupLayout(hardwarePanel);
        hardwarePanel.setLayout(hardwarePanelLayout);
        hardwarePanelLayout.setHorizontalGroup(
            hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(hardwarePanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(jLabel13)
                    .add(jLabel3)
                    .add(jLabel2)
                    .add(jLabel1)
                    .add(jLabel15))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(inputs, 0, 152, Short.MAX_VALUE)
                    .add(mcu, 0, 152, Short.MAX_VALUE)
                    .add(clock, 0, 152, Short.MAX_VALUE)
                    .add(chainID, 0, 152, Short.MAX_VALUE)
                    .add(bootloader, 0, 152, Short.MAX_VALUE))
                .addContainerGap())
        );
        hardwarePanelLayout.setVerticalGroup(
            hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(hardwarePanelLayout.createSequentialGroup()
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(inputs, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(mcu, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(clock))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(bootloader, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel13, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 21, Short.MAX_VALUE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(hardwarePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(chainID, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel15, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 21, Short.MAX_VALUE))
                .addContainerGap())
        );

        midiPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Midi Devices"));

        inputLabel.setText("Input:");

        outputLabel.setText("Output:");

        through.setEnabled(false);

        jLabel14.setText("Through:");

        enableMidiThrough.setText("Enable MIDI Through");
        enableMidiThrough.setToolTipText("<html>\n&nbsp;Enable MIDI Through and select a device from the&nbsp;<br>\n&nbsp;list below, if you want all MIDI messages received&nbsp;<br>\n&nbsp;through the input to be forwarded to that device.&nbsp;\n</html>");
        enableMidiThrough.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        enableMidiThrough.setMargin(new java.awt.Insets(0, 0, 0, 0));

        useSameDevice.setText("Use same device for In & Out");
        useSameDevice.setToolTipText("<html>\n&nbsp;Normally you will have this selected&nbsp;<br>\n&nbsp;as you will use the Megadrum MIDI&nbsp;<br>\n&nbsp;interface as both input and output.&nbsp;\n</html>");
        useSameDevice.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        useSameDevice.setMargin(new java.awt.Insets(0, 0, 0, 0));

        org.jdesktop.layout.GroupLayout midiPanelLayout = new org.jdesktop.layout.GroupLayout(midiPanel);
        midiPanel.setLayout(midiPanelLayout);
        midiPanelLayout.setHorizontalGroup(
            midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(midiPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, inputLabel)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, outputLabel)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel14))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(input, 0, 169, Short.MAX_VALUE)
                    .add(output, 0, 169, Short.MAX_VALUE)
                    .add(enableMidiThrough)
                    .add(useSameDevice)
                    .add(through, 0, 169, Short.MAX_VALUE))
                .addContainerGap())
        );
        midiPanelLayout.setVerticalGroup(
            midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, midiPanelLayout.createSequentialGroup()
                .add(useSameDevice)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(input, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(inputLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 21, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(output, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(outputLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 21, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(enableMidiThrough)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(midiPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(through, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(jLabel14, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 21, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        quickAccessPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Quick Access"));

        enableQuickAccess.setText("Enable Quick Access");
        enableQuickAccess.setToolTipText("<html>\n&nbsp;Enabling Quick Access will allow you to select&nbsp;<br>\n&nbsp;a pad from the list by hitting a pad in your&nbsp;<br>\n&nbsp;drumkit while you have the hihat pedal closed&nbsp;\n</html>");
        enableQuickAccess.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        enableQuickAccess.setMargin(new java.awt.Insets(0, 0, 0, 0));

        jLabel7.setText("Pad velocity threshold:");
        jLabel7.setToolTipText("<html> &nbsp;Only pad hits with velocity above this&nbsp;<br> &nbsp;value will make the application jump to the&nbsp;<br> &nbsp;corresponding pad configuration panel&nbsp;</html>");

        jLabel6.setText("Hihat pedal threshold:");
        jLabel6.setToolTipText("<html>&nbsp;\nHihat pedal is considered to be closed if the&nbsp;<br>&nbsp;\nreceived value is higher than this value.&nbsp;<br>&nbsp;\nIt is recommended to set it to the same value&nbsp;<br>&nbsp;\nas the \"Closed Level\" in the Hihat panel.&nbsp;\n</html>");

        qaPad.setToolTipText("<html> &nbsp;Only pad hits with velocity above this&nbsp;<br> &nbsp;value will make the application jump to the&nbsp;<br> &nbsp;corresponding pad configuration panel&nbsp;</html>");
        qaPad.setEnabled(false);

        qaPedal.setToolTipText("<html>&nbsp;\nHihat pedal is considered to be closed if the&nbsp;<br>&nbsp;\nreceived value is higher than this value.&nbsp;<br>&nbsp;\nIt is recommended to set it to the same value&nbsp;<br>&nbsp;\nas the \"Closed Level\" in the Hihat panel.&nbsp;\n</html>");
        qaPedal.setEnabled(false);

        org.jdesktop.layout.GroupLayout quickAccessPanelLayout = new org.jdesktop.layout.GroupLayout(quickAccessPanel);
        quickAccessPanel.setLayout(quickAccessPanelLayout);
        quickAccessPanelLayout.setHorizontalGroup(
            quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(quickAccessPanelLayout.createSequentialGroup()
                .add(quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(quickAccessPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .add(quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel7)
                            .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel6))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(qaPedal, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 65, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(qaPad, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 65, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                    .add(quickAccessPanelLayout.createSequentialGroup()
                        .add(12, 12, 12)
                        .add(enableQuickAccess)))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        quickAccessPanelLayout.setVerticalGroup(
            quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(quickAccessPanelLayout.createSequentialGroup()
                .add(enableQuickAccess, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 14, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel7)
                    .add(qaPad, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(quickAccessPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel6)
                    .add(qaPedal, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        rimSwitchPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Rim Switch"));

        jLabel9.setText("Threshold:");
        jLabel9.setToolTipText("<html>&nbsp;Only pad hits with velocity above&nbsp;<br>\n&nbsp;this value will produce changes in the&nbsp;<br>\n&nbsp;rim switch light inside the Midi Monitor&nbsp;</html>");

        rimSwitch.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0", "10", "20", "30", "40", "50", "60" }));
        rimSwitch.setToolTipText("<html>&nbsp;Only pad hits with velocity above&nbsp;<br> &nbsp;this value will produce changes in the&nbsp;<br> &nbsp;rim switch light inside the Midi Monitor&nbsp;</html>");

        org.jdesktop.layout.GroupLayout rimSwitchPanelLayout = new org.jdesktop.layout.GroupLayout(rimSwitchPanel);
        rimSwitchPanel.setLayout(rimSwitchPanelLayout);
        rimSwitchPanelLayout.setHorizontalGroup(
            rimSwitchPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(rimSwitchPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(rimSwitchPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(rimSwitchPanelLayout.createSequentialGroup()
                        .add(6, 6, 6)
                        .add(rimSwitch, 0, 55, Short.MAX_VALUE))
                    .add(jLabel9))
                .addContainerGap())
        );
        rimSwitchPanelLayout.setVerticalGroup(
            rimSwitchPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(rimSwitchPanelLayout.createSequentialGroup()
                .add(jLabel9)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(rimSwitch, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 21, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        themePanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Look & Feel / Color Theme"));

        jLabel10.setText("Look & Feel:");

        jLabel11.setText("Theme:");

        org.jdesktop.layout.GroupLayout themePanelLayout = new org.jdesktop.layout.GroupLayout(themePanel);
        themePanel.setLayout(themePanelLayout);
        themePanelLayout.setHorizontalGroup(
            themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(themePanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel10)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jLabel11))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(lookandfeel, 0, 127, Short.MAX_VALUE)
                    .add(theme, 0, 127, Short.MAX_VALUE))
                .addContainerGap())
        );
        themePanelLayout.setVerticalGroup(
            themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(themePanelLayout.createSequentialGroup()
                .add(themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel10, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(lookandfeel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(themePanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(jLabel11, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(theme, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        apply.setText("Apply");

        sysexPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("SYSEX send"));

        jLabel12.setText("Wait time (ms):");
        jLabel12.setToolTipText("<html> &nbsp; Sets the time application will wait before&nbsp;<br> &nbsp; sending each sysex of an \"all settings\" action&nbsp;");

        waitTime.setToolTipText("<html> &nbsp;\nSets the time application will wait before&nbsp;<br> &nbsp;\nsending each sysex of an \"all settings\" action&nbsp;");

        org.jdesktop.layout.GroupLayout sysexPanelLayout = new org.jdesktop.layout.GroupLayout(sysexPanel);
        sysexPanel.setLayout(sysexPanelLayout);
        sysexPanelLayout.setHorizontalGroup(
            sysexPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(sysexPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(sysexPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(sysexPanelLayout.createSequentialGroup()
                        .add(6, 6, 6)
                        .add(waitTime, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE))
                    .add(jLabel12))
                .addContainerGap())
        );
        sysexPanelLayout.setVerticalGroup(
            sysexPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(sysexPanelLayout.createSequentialGroup()
                .add(jLabel12)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(waitTime, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        loadSendPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Loading / Sending"));

        enableLiveEditing.setText("Live Editing");
        enableLiveEditing.setToolTipText("<html>\n&nbsp;Settings you have edited will be sent&nbsp;<br>\n&nbsp;automatically just after you edit them&nbsp;\n</html>");
        enableLiveEditing.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        enableLiveEditing.setMargin(new java.awt.Insets(0, 0, 0, 0));

        enableLoadAtStartup.setText("Load MD settings at startup");
        enableLoadAtStartup.setToolTipText("Load all settings from MD when you start the application");
        enableLoadAtStartup.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        enableLoadAtStartup.setMargin(new java.awt.Insets(0, 0, 0, 0));

        org.jdesktop.layout.GroupLayout loadSendPanelLayout = new org.jdesktop.layout.GroupLayout(loadSendPanel);
        loadSendPanel.setLayout(loadSendPanelLayout);
        loadSendPanelLayout.setHorizontalGroup(
            loadSendPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(loadSendPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(loadSendPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(enableLiveEditing)
                    .add(enableLoadAtStartup))
                .addContainerGap(49, Short.MAX_VALUE))
        );
        loadSendPanelLayout.setVerticalGroup(
            loadSendPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(loadSendPanelLayout.createSequentialGroup()
                .add(enableLiveEditing, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 14, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(enableLoadAtStartup, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 14, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(apply)
                    .add(hardwarePanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(midiPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(themePanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(layout.createSequentialGroup()
                        .add(rimSwitchPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(sysexPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .add(loadSendPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .add(quickAccessPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
                    .add(layout.createSequentialGroup()
                        .add(hardwarePanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(midiPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(apply))
                    .add(layout.createSequentialGroup()
                        .add(loadSendPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(quickAccessPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                            .add(rimSwitchPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(sysexPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(themePanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void fillInList() {
        String[] devices = MidiCommon.getInputDeviceList();
        if (devices.length == 0) {
            JOptionPane.showMessageDialog(this, "There isn't any MIDI input device available", "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            input.removeAllItems();
            for (int i = 0; i < devices.length; i++) {
                input.addItem(devices[i]);
            }
        }
    }
    private void fillOutputList() {
        String[] devices = MidiCommon.getOutputDeviceList();
        if (devices.length == 0) {
            JOptionPane.showMessageDialog(this, "There isn't any MIDI output device available", "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            output.removeAllItems();
            for (int i = 0; i < devices.length; i++) {
                output.addItem(devices[i]);
            }
        }
    }
    private void fillThroughList() {
        String[] devices = MidiCommon.getOutputDeviceListExclude((String)(output.getSelectedItem()));
        if (devices.length == 0) {
            JOptionPane.showMessageDialog(this, "There isn't any MIDI through device available", "Warning", JOptionPane.WARNING_MESSAGE);
        } else {
            through.removeAllItems();
            for (int i = 0; i < devices.length; i++) {
                through.addItem(devices[i]);
            }
        }
    }

    public void itemStateChanged(ItemEvent e) {
        if (e.getSource() == enableQuickAccess) {
            //enable quick access
            if (e.getStateChange() == ItemEvent.SELECTED) {
                qaPad.setEnabled(true);
                qaPedal.setEnabled(true);
            } else {
                qaPad.setEnabled(false);
                qaPedal.setEnabled(false);
            }
        } else if (e.getSource() == useSameDevice) {
            //use same device for input & output
            if(useSameDevice.isSelected()){
                inputLabel.setText("In&Out:");
                outputLabel.setEnabled(false);
                output.setEnabled(false);
                output.setSelectedItem(input.getSelectedItem());
            }else{
                inputLabel.setText("Input:");
                outputLabel.setEnabled(true);
                output.setEnabled(true);
            }
        } else if (e.getSource() == input && useSameDevice.isSelected()) {
            //if input changed and useSameDevice selected, select the same output
            output.setSelectedItem(input.getSelectedItem());
        } else if (e.getSource() == output) {
            Object throughSelected = through.getSelectedItem();
            fillThroughList();
            through.setSelectedItem(throughSelected);
            
        } else if (e.getSource() == enableMidiThrough) {
            //enable midi through
            through.setEnabled(enableMidiThrough.isSelected());
        } else if (e.getSource() == lookandfeel) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                if (lookandfeel.getSelectedIndex() < 4) { //METAL THEMES
                    theme.setModel(new javax.swing.DefaultComboBoxModel(Common.METALTHEMES_NAMES));
                } else if (lookandfeel.getSelectedIndex() == 4) {
                    theme.setModel(new javax.swing.DefaultComboBoxModel(Common.NIMRODTHEMES_NAMES));
                } else if (lookandfeel.getSelectedIndex() == 5) {
                    theme.setModel(new javax.swing.DefaultComboBoxModel(Common.LIPSTIKTHEMES_NAMES));
                } else if (lookandfeel.getSelectedIndex() == 6) {
                    theme.setModel(new javax.swing.DefaultComboBoxModel(Common.INFONODETHEMES_NAMES));
                }
            }
        } else if (e.getSource() == mcu) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                inputs.setModel(new javax.swing.DefaultComboBoxModel(Common.NUM_INPUTS[mcu.getSelectedIndex()]));
                //will try to set the current number of inputs, if not possible a default value will be autoselected
                inputs.setSelectedItem("" + (parent.getNumberOfInputs() + 1));
            }
        }
    }

    public void actionPerformed(ActionEvent ev) {
        String mc = ((String) mcu.getSelectedItem()).substring(6);
        String cl = ((String) clock.getSelectedItem()).substring(0, 2);
        parent.setNumberOfInputs(Integer.parseInt((String) inputs.getSelectedItem()));
        parent.setMCU(mc);
        parent.setClock(cl);
        parent.setBootloader(bootloader.getSelectedIndex());

        parent.setInputDeviceName((String) (input.getSelectedItem()));
        parent.setOutputDeviceName((String) (output.getSelectedItem()));
        if(enableMidiThrough.isSelected()){
            parent.setThroughDeviceName((String) (through.getSelectedItem()));
        }else{
            parent.setThroughDeviceName(null);
        }

        parent.setChainID(chainID.getSelectedIndex());

        parent.setLiveEditingEnabled(enableLiveEditing.isSelected());
        parent.setLoadAtStartupEnabled(enableLoadAtStartup.isSelected());

        parent.setQuickAccessEnabled(enableQuickAccess.isSelected());
        parent.setQuickAccessPadThreshold(((CustomSpinnerModel) qaPad.getModel()).getIntValue());
        parent.setQuickAccessPedalThreshold(((CustomSpinnerModel) qaPedal.getModel()).getIntValue());

        parent.setRimSwitchThreshold(rimSwitch.getSelectedIndex() * 10);

        parent.setSysexWaitTime(((CustomSpinnerModel) waitTime.getModel()).getIntValue());

        parent.setLookAndFeel(lookandfeel.getSelectedIndex());
        parent.setTheme(theme.getSelectedIndex());

        //save everything to file
        parent.updateConfigurationFile();
        parent.updateInputNamesFile();


        //if number of inputs has changed ask for reboot
        if (selectedInputs != inputs.getSelectedIndex() ||
                selectedLook != lookandfeel.getSelectedIndex() ||
                selectedTheme != theme.getSelectedIndex()) {
                JOptionPane.showMessageDialog(this,
                        "Application interface will be restarted\nfor the changes to take effect.",
                        "Warning", JOptionPane.WARNING_MESSAGE);
                //save current settings
                byte[] b = parent.getAllSettingsFromGUI();
                if (b != null) {
                    SysexFile.saveFile(b, Common.getUserProfileFolder() + Common.DEFAULT_CONFIG_FILE);
                }
                //close main window
                parent.dispose();
                //reboot app
                java.awt.EventQueue.invokeLater(new Runnable() {

                    public void run() {
                        new MegadrumConfigTool(false);
                    }
                });
        }
        //close
        dispose();
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton apply;
    private javax.swing.JComboBox bootloader;
    private javax.swing.JComboBox chainID;
    private javax.swing.JComboBox clock;
    private javax.swing.JCheckBox enableLiveEditing;
    private javax.swing.JCheckBox enableLoadAtStartup;
    private javax.swing.JCheckBox enableMidiThrough;
    private javax.swing.JCheckBox enableQuickAccess;
    private javax.swing.JComboBox input;
    private javax.swing.JLabel inputLabel;
    private javax.swing.JComboBox inputs;
    private javax.swing.JComboBox lookandfeel;
    private javax.swing.JComboBox mcu;
    private javax.swing.JComboBox output;
    private javax.swing.JLabel outputLabel;
    private javax.swing.JSpinner qaPad;
    private javax.swing.JSpinner qaPedal;
    private javax.swing.JComboBox rimSwitch;
    private javax.swing.JComboBox theme;
    private javax.swing.JComboBox through;
    private javax.swing.JCheckBox useSameDevice;
    private javax.swing.JSpinner waitTime;
    // End of variables declaration//GEN-END:variables
    private MegadrumConfigTool parent;
    private int selectedInputs,  selectedLook,  selectedTheme;
}
